//-----------------------------------------------------------------------------
//																Vector2 class
//-----------------------------------------------------------------------------
template <typename T>
Vector2<T>::Vector2()
: x(0)
, y(0)
{

}

template <typename T>
Vector2<T>::Vector2(T _x, T _y)
: x(_x)
, y(_y)
{

}

template <typename T>
Vector2<T>::Vector2(const Vector2<T>& v)
: x(v.x)
, y(v.y)
{
	
}

template <typename T>
Vector2<T>::operator float* ()
{
	return this;
}

template <typename T>
Vector2<T>::operator const float* () const
{
	return this;
}

template <typename T>
Vector2<T>& Vector2<T>::operator= (const Vector2<T>& rhs)
{
	if (this != &rhs)
	{
		x = rhs.x;
		y = rhs.y;
	}
	return *this;
}

template <typename T>
Vector2<T>& Vector2<T>::operator+= (const Vector2<T>& rhs)
{
	x += rhs.x;
	y += rhs.y;
	return *this;
}

template <typename T>
Vector2<T>& Vector2<T>::operator-= (const Vector2<T>& rhs)
{
	x -= rhs.x;
	y -= rhs.y;
	return *this;
}

template <typename T>
Vector2<T>&	Vector2<T>::operator*= (T rhs)
{
	x *= rhs;
	y *= rhs;
	return *this;
}

template <typename T>
Vector2<T>&	Vector2<T>::operator/= (T rhs)
{
	x /= rhs;
	y /= rhs;
	return *this;
}

template <typename T>
Vector2<T> Vector2<T>::operator+ () const
{
	return *this;
}

template <typename T>
Vector2<T> Vector2<T>::operator- () const
{
	return -1 * *this;
}

template <typename T>
Vector2<T> Vector2<T>::operator+ (const Vector2<T>& rhs) const
{
	Vector2<T> result(*this);
	result += rhs;
	return result;
}

template <typename T>
Vector2<T> Vector2<T>::operator- (const Vector2<T>& rhs) const
{
	Vector2<T> result(*this);
	result -= rhs;
	return result;
}

template <typename T>
Vector2<T> operator* (T number, const Vector2<T>& vector)
{
	Vector2<T> result(vector);
	result *= number;
	return result;
}

template <typename T>
bool Vector2<T>::operator== (const Vector2<T>& rhs) const
{
	return x == rhs.x && y == rhs.y;
}

template <typename T>
bool Vector2<T>::operator!= (const Vector2<T>& rhs) const
{
	return !(*this == rhs);
}

//-----------------------------------------------------------------------------
//																Vector3 class
//-----------------------------------------------------------------------------
template <typename T>
Vector3<T>::Vector3()
: x(0)
, y(0)
, z(0)
{

}

template <typename T>
Vector3<T>::Vector3(T _x, T _y, T _z)
: x(_x)
, y(_y)
, z(_z)
{

}

template <typename T>
Vector3<T>::Vector3(const Vector3<T>& v)
: x(v.x)
, y(v.y)
, z(v.z)
{

}

template <typename T>
Vector3<T>::operator float* ()
{
	return this;
}

template <typename T>
Vector3<T>::operator const float* () const
{
	return this;
}

template <typename T>
Vector3<T>& Vector3<T>::operator= (const Vector3<T>& rhs)
{
	if (this != &rhs)
	{
		x = rhs.x;
		y = rhs.y;
		z = rhs.z;
	}
	return *this;
}

template <typename T>
Vector3<T>& Vector3<T>::operator+= (const Vector3<T>& rhs)
{
	x += rhs.x;
	y += rhs.y;
	z += rhs.z;
	return *this;
}

template <typename T>
Vector3<T>& Vector3<T>::operator-= (const Vector3<T>& rhs)
{
	x -= rhs.x;
	y -= rhs.y;
	z -= rhs.z;
	return *this;
}

template <typename T>
Vector3<T>& Vector3<T>::operator*= (T rhs)
{
	x *= rhs;
	y *= rhs;
	z *= rhs;
	return *this;
}

template <typename T>
Vector3<T>& Vector3<T>::operator/= (T rhs)
{
	x /= rhs;
	y /= rhs;
	z /= rhs;
	return *this;
}

template <typename T>
Vector3<T> Vector3<T>::operator+ () const
{
	return *this;
}

template <typename T>
Vector3<T> Vector3<T>::operator- () const
{
	return -1 * *this;
}

template <typename T>
T	Vector3<T>::operator* (const Vector3<T>& rhs) const
{
	return x*rhs.x + y*rhs.y + z*rhs.z;
}

template <typename T>
Vector3<T> Vector3<T>::operator^ (const Vector3<T>& rhs) const
{
	Vector3<T> result;
	result.x = y*rhs.z - z*rhs.y;
	result.y = z*rhs.x - x*rhs.z;
	result.z = x*rhs.y - y*rhs.x;
	return result;
}

template <typename T>
Vector3<T> Vector3<T>::operator+ (const Vector3<T>& rhs) const
{
	Vector3<T> result(*this);
	result += rhs;
	return result;
}

template <typename T>
Vector3<T> Vector3<T>::operator- (const Vector3<T>& rhs) const
{
	Vector3<T> result(*this);
	result -= rhs;
	return result;
}

template <typename T>
Vector3<T> operator* (T number, const Vector3<T>& vector)
{
	Vector3<T> result(vector);
	result *= number;
	return result;
}

template <typename T>
bool Vector3<T>::operator== (const Vector3<T>& rhs) const
{
	return x == rhs.x && y == rhs.y && z = rhs.z;
}

template <typename T>
bool Vector3<T>::operator!= (const Vector3<T>& rhs) const
{
	return !(*this == rhs);
}

template <typename T>
T	Vector3<T>::length() const
{
	return sqrt(x*x + y*y + z*z);
}

template <typename T>
void Vector3<T>::normalize()
{
	*this /= length();
}

template <typename T>
Vector3<T> Vector3<T>::normalized() const
{
	Vector3<T> result(*this);
	result.normalize();
	return result;
}

template <typename T>
Vector3<T> Vector3<T>::cross(const Vector3<T>& v)
{
	return *this ^ v;
}

template <typename T>
T Vector3<T>::dot(const Vector3<T>& v)
{
	return *this * v;
}

//-----------------------------------------------------------------------------
//																Vector4 class
//-----------------------------------------------------------------------------
template <typename T>
Vector4<T>::Vector4()
: x(0)
, y(0)
, z(0)
, w(0)
{

}

template <typename T>
Vector4<T>::Vector4(T _x, T _y, T _z, T _w)
: x(_x)
, y(_y)
, z(_z)
, w(_w)
{

}